using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using M0;
using Newtonsoft.Json;
using Palmmedia.ReportGenerator.Core.Common;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.Networking;

static public class GameAssetHelper
    {
        /// <summary>
        /// 检测StreamingAsset下的资源包版本
        /// StreamingAsset 和 Persistent对比
        /// </summary>
        /// <param name="callback"></param>
        static public async void CheckAssetPackageVersion(RuntimePlatform platform, Action callback)
        {
            switch (platform)
            {
                //android沙盒用www访问
                case RuntimePlatform.Android:
                {
                    AndroidCheckAssetPackageVersion(platform, callback);
                }
                    break;
                default:
                {
                    IOSCheckAssetPackageVersion(platform, callback);
                }
                    break;
            }
        }

        /// <summary>
        /// 生成资源包构建信息
        /// </summary>
        static public void GenPackageBuildInfo(string ouptputPath, RuntimePlatform platform, string assetSVC = "", string scriptSVC = "", string tableSVC = "")
        {
            string PACKAGE_BUILD_INFO_PATH = "PackageBuild.Info";
            var path = string.Format("{0}/{1}/{2}", ouptputPath, GetPlatformPath(platform), PACKAGE_BUILD_INFO_PATH);

            //写入buildinfo内容
            var buildinfo = new PackageBuildInfo();
            DateTime startTime = TimeZoneInfo.ConvertTime(new System.DateTime(1970, 1, 1), TimeZoneInfo.Utc, TimeZoneInfo.Local); // 当地时区
            long timeStamp = (long) (DateTime.Now - startTime).TotalSeconds;
            buildinfo.BuildTime = timeStamp;
            var content = JsonConvert.SerializeObject(buildinfo);
            //写入本地
            if (File.Exists(path))
            {
                File.Delete(path);
            }

            File.WriteAllText(path, content);
        }

        /// <summary>
        /// 母包资源检测逻辑
        /// </summary>
        /// <returns></returns>
        static private async void AndroidCheckAssetPackageVersion(RuntimePlatform platform, Action callback)
        {
            Debug.Log("【资源包】执行母包资源检测逻辑！");
            //路径初始化
            var targetPath = string.Format("{0}/{1}", Application.persistentDataPath, GetPlatformPath(platform));
            string source = "";
            if (Application.isEditor)
            {
                //编辑器下 从加载目标拷贝
                source = GameConfig.GetLoadPath(AssetLoadPathType.StreamingAsset);
            }
            else
            {
                source = Application.streamingAssetsPath;
            }

            string PACKAGE_BUILD_INFO_PATH = "PackageBuild.Info";
            
            var sourcePath = string.Format("{0}/{1}", source, GetPlatformPath(platform));
            //PackageInfo
            var persistentPackageInfoPath = string.Format("{0}/{1}", targetPath, PACKAGE_BUILD_INFO_PATH);
            var streamingPackageinfoPath = string.Format("{0}/{1}", sourcePath, PACKAGE_BUILD_INFO_PATH);
            UnityWebRequest www = new UnityWebRequest(streamingPackageinfoPath);
            await www.SendWebRequest();
            if (www.error != null)
            {
                //不存在Streaming配置
                callback?.Invoke();
                await Task.Yield();
            }
            else
            {
                //判断版本
                if (File.Exists(persistentPackageInfoPath))
                {
                    var content = File.ReadAllText(persistentPackageInfoPath);
                    var persistentPackageInfo = JsonConvert.DeserializeObject<PackageBuildInfo>(content);
                    var streamingPackageInfo = JsonConvert.DeserializeObject<PackageBuildInfo>(www.downloadHandler.text);
                    if (persistentPackageInfo.BuildTime >= streamingPackageInfo.BuildTime)
                    {
                        Debug.Log("【母包资源检测】不复制，Streaming无新资源");
                        callback?.Invoke();
                        await Task.Yield();
                    }
                    else
                    {
                        Debug.Log("【母包资源检测】复制，Streaming有新资源");
                        //Streaming版本比较新
                        //复制Stream的packageinfo 到persistent
                        File.WriteAllBytes(persistentPackageInfoPath, www.downloadHandler.data);
                    }
                }
                else
                {
                    Debug.Log("【母包资源检测】第一次创建资源包info到persistent目录");
                    //persistent版本不存在
                    //复制Stream的packageinfo 到persistent
                    File.WriteAllBytes(persistentPackageInfoPath,www.downloadHandler.data);
                }
            }
            
        string ASSET_ROOT_PATH = "Art";
string ASSET_CONFIG_PATH = ASSET_ROOT_PATH + "/ArtConfig.Info";
string ASSET_TYPES_PATH = ASSET_ROOT_PATH + "/AssetTypeConfig.Info";
            //要拷贝的资源
            string[] copyFiles = new string[]
            {
                // ScriptLoder.DLL_PATH, ScriptLoder.DLL_PATH + ".pdb", //Dll
                // SqliteLoder.LOCAL_DB_PATH, //db
                ASSET_CONFIG_PATH, ASSET_TYPES_PATH, //ArtConfig
            };
            //开始拷贝逻辑
            for (int i = 0; i < copyFiles.Length; i++)
            {
                //拷贝逻辑
                var copyFile = copyFiles[i];
                var persistentPath = string.Format("{0}/{1}", targetPath, copyFile);
                var streamingPath = string.Format("{0}/{1}", sourcePath, copyFile);
                www = new UnityWebRequest(streamingPath);
                await www.SendWebRequest();
                if (www.error == null)
                {
                    File.WriteAllBytes(persistentPath, www.downloadHandler.data);
                    Debug.Log("【母包资源检测】复制成功:" + copyFile);
                }
                else
                {
                    Debug.LogError("【母包资源检测】复制失败:" + copyFile);
                }
            }


            await Task.Yield();
            callback?.Invoke();
        }
        
        public static string GetPlatformPath(RuntimePlatform platform)
        {
            switch (platform)
            {
                case RuntimePlatform.WindowsEditor:
                case RuntimePlatform.WindowsPlayer:
                // return "Windows";
                case RuntimePlatform.Android:
                    return "Android";
                case RuntimePlatform.OSXEditor:
                case RuntimePlatform.OSXPlayer:
                case RuntimePlatform.IPhonePlayer:
                    return "iOS";
            }

            return "";
        }

        /// <summary>
        /// 母包资源检测逻辑
        /// </summary>
        /// <returns></returns>
        static private void IOSCheckAssetPackageVersion(RuntimePlatform platform, Action callback)
        {
            Debug.Log("【资源包】执行母包资源检测逻辑！");
            //路径初始化
            var targetPath = string.Format("{0}/{1}", Application.persistentDataPath, GetPlatformPath(platform));
            string source = "";
            if (Application.isEditor)
            {
                //编辑器下 从加载目标拷贝
                source = GameConfig.GetLoadPath(AssetLoadPathType.StreamingAsset);
                if (source == Application.persistentDataPath)
                {
                    var s1= $"{Application.streamingAssetsPath}/{GetPlatformPath(platform)}";
                    if (Directory.Exists(s1))
                    {
                        source = Application.streamingAssetsPath;
                    }
                    else
                    {
                        string ProjectRoot             = Application.dataPath.Replace("/Assets", "");
                        //DevOps路径
                        string DevOpsPath = ProjectRoot + "/DevOps";
                        string DevOpsPublishAssetsPath  = DevOpsPath + "/PublishAssets";
                        
                        
                        var s2 =$"{DevOpsPublishAssetsPath}/{GetPlatformPath(platform)}";
                        if (Directory.Exists(s2))
                        {
                            source = DevOpsPublishAssetsPath;
                        }
                        else
                        {
                            Debug.LogError("【资源包】本地无资源,可能逻辑出错,请检查!");
                        }
                    }
                }
            }
            else
            {
                source = Application.streamingAssetsPath;
            }

            var sourcePath = $"{source}/{GetPlatformPath(platform)}";

            //packageinfo
            string PACKAGE_BUILD_INFO_PATH = "PackageBuild.Info";
            
            var persistentPackageInfoPath = string.Format("{0}/{1}", targetPath, PACKAGE_BUILD_INFO_PATH);
            var streamingPackageinfoPath = string.Format("{0}/{1}", sourcePath, PACKAGE_BUILD_INFO_PATH);
            if (!File.Exists(streamingPackageinfoPath))
            {
                //不存在Streaming配置
                Debug.LogError("【资源包】拷贝失败,不存在：" + streamingPackageinfoPath);
                callback?.Invoke();
            }
            else
            {
                var streamingPackageInfoContent = File.ReadAllText(streamingPackageinfoPath);
                //persitent存在，判断版本
                if (File.Exists(persistentPackageInfoPath))
                {
                    var content = File.ReadAllText(persistentPackageInfoPath);
                    var persistentPackageInfo = JsonConvert.DeserializeObject<PackageBuildInfo>(content);

                    var streamingPackageInfo = JsonConvert.DeserializeObject<PackageBuildInfo>(streamingPackageInfoContent);
                    if (persistentPackageInfo.BuildTime >= streamingPackageInfo.BuildTime)
                    {
                        //跳出，检测结束
                        Debug.Log("【母包资源检测】不复制，Streaming 无新资源");
                        callback?.Invoke();

                        return;
                    }
                    else
                    {
                        Debug.Log("【母包资源检测】复制，Streaming 有新资源");
                        //Streaming版本比较新
                        //复制Stream的packageinfo 到persistent
                        File.WriteAllText(persistentPackageInfoPath, streamingPackageInfoContent);
                    }
                }
                else
                {
                    Debug.Log("【母包资源检测】第一次创建资源包info到persistent目录");
                    //persistent版本不存在
                    //复制Stream的packageinfo 到persistent
                    File.WriteAllText(persistentPackageInfoPath, streamingPackageInfoContent);
                }
            }

            string ASSET_ROOT_PATH = "Art";
            string ASSET_CONFIG_PATH = ASSET_ROOT_PATH + "/ArtConfig.Info";
            string ASSET_TYPES_PATH = ASSET_ROOT_PATH + "/AssetTypeConfig.Info";
        
            //要拷贝的资源
            string[] copyFiles = new string[]
            {
                // ScriptLoder.DLL_PATH, ScriptLoder.DLL_PATH + ".pdb", //Dll
                // SqliteLoder.LOCAL_DB_PATH, //db
                ASSET_CONFIG_PATH, ASSET_TYPES_PATH, //ArtConfig
            };

            //开始拷贝逻辑
            for (int i = 0; i < copyFiles.Length; i++)
            {
                var copyFile = copyFiles[i];
                //复制新版本的DLL 
                var persistentPath = string.Format("{0}/{1}", targetPath, copyFile);
                var streamingPath = string.Format("{0}/{1}", sourcePath, copyFile);

                if (File.Exists(streamingPath))
                {
                    File.WriteAllBytes(persistentPath, File.ReadAllBytes(streamingPath));
                    Debug.Log("【母包资源检测】复制成功:" + copyFile);
                }
                else
                {
                    Debug.LogError("【母包资源检测】复制失败:" + copyFile);
                }
            }

            //结束
            callback?.Invoke();
        }
    }
    
    
public class PackageBuildInfo
{
    /// <summary>
    /// 构建时间
    /// </summary>
    public long BuildTime = 0;

    /// <summary>
    /// AB构建svc版本号
    /// </summary>
    public string AssetBundleSVCVersion = "";

    /// <summary>
    /// 脚本构建svc版本号
    /// </summary>
    public string ScriptSVCVersion = "";

    /// <summary>
    /// 表格构建svc版本号
    /// </summary>
    public string TableSVCVersion = "";
}

public enum AssetLoadPathType
{
    Editor = 0,

    /// <summary>
    /// 用户可读写沙盒
    /// </summary>
    Persistent,

    /// <summary>
    /// Streaming
    /// </summary>
    StreamingAsset,

    /// <summary>
    /// devop的发布目录
    /// </summary>
    DevOpsPublish
}

    [Serializable]
    public class GameConfig
    {
        [LabelText("代码路径")]
        public AssetLoadPathType CodeRoot = AssetLoadPathType.Editor;

        [LabelText("SQLite路径")]
        public AssetLoadPathType SQLRoot = AssetLoadPathType.Editor;

        [LabelText("资源路径")]
        public AssetLoadPathType ArtRoot = AssetLoadPathType.Editor;


        // [LabelText("热更代码执行模式")]
        // public HotfixCodeRunMode CodeRunMode = HotfixCodeRunMode.ByILRuntime;

        [LabelText("是否开启ILRuntime调试")]
        public bool IsDebuggerILRuntime = false;

        [LabelText("是否打印日志")]
        public bool IsDebugLog = true;


        [LabelText("文件服务器")]
        public string FileServerUrl = "192.168.8.68";

        [LabelText("Gate服务器")]
        public string GateServerIp = "";

        public int Port;

        [LabelText("是否热更")]
        public bool IsHotfix = false;

        [LabelText("是否联网")]
        public bool IsNeedNet = false;

        /// <summary>
        /// 获取加载路径
        /// </summary>
        /// <param name="assetLoadPathType"></param>
        static public string GetLoadPath(AssetLoadPathType assetLoadPathType)
        {
            var path = "";
            //Editor下按照加载路径区分
            if (Application.isEditor)
            {
                switch (assetLoadPathType)
                {
                    case AssetLoadPathType.Persistent:
                        path = Application.persistentDataPath;
                        break;
                    case AssetLoadPathType.Editor:
                    case AssetLoadPathType.StreamingAsset:
                    {
                        path = Application.streamingAssetsPath;
                    }
                        break;
                    case AssetLoadPathType.DevOpsPublish:
                    {
                        
                        string ProjectRoot             = Application.dataPath.Replace("/Assets", "");
                        //DevOps路径
                        string DevOpsPath = ProjectRoot + "/DevOps";
                        string DevOpsPublishAssetsPath  = DevOpsPath + "/PublishAssets";

                        path = DevOpsPublishAssetsPath;
                    }
                        break;
                }
            }
            else
            {
                //真机环境默认都在persistent下，因为需要io.不在的各个模块会自行拷贝
                path = Application.persistentDataPath;
            }

            return path;
        }
    }